package com.example.blenderandroid;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class View3D extends SurfaceView implements SurfaceHolder.Callback, Navigation3DGestureDetector.OnNavigation3DGesture {
	
	private DrawThread m_DrawThread;
	
	private Navigation3DGestureDetector m_GestureDetector;
	
	public View3D(Context context, AttributeSet attrs) {
		super(context, attrs);

		SurfaceHolder surfaceHolder = getHolder();
		surfaceHolder.addCallback(this);
		
		m_DrawThread = new DrawThread();
        
        m_GestureDetector = new Navigation3DGestureDetector(this);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent evt) {
		return m_GestureDetector.onTouchEvent(evt);
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		m_DrawThread.setSurfaceSize(width, height);
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		m_DrawThread.m_IsRunning = true;
		m_DrawThread.start();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		m_DrawThread.m_IsRunning = false;
		boolean isNotStopped = true;
		while (isNotStopped) {
			try {
				m_DrawThread.join();
				isNotStopped = false;
			} catch (InterruptedException ex) { }
		}
	}
	
	private class DrawThread extends Thread {
		private SurfaceHolder m_SurfaceHolder;
		
		public boolean m_IsRunning;
		
		private int m_SurfaceWidth, m_SurfaceHeight;
		
		private Paint m_BackgroundPaint, m_MainAxisPaint, m_RotateCirclePaint;
		
		public DrawThread() {
			m_SurfaceHolder = View3D.this.getHolder();
			m_IsRunning = false;
			
			m_BackgroundPaint = new Paint();
			m_BackgroundPaint.setColor(Color.WHITE);
			m_BackgroundPaint.setStyle(Paint.Style.FILL);
			
			m_MainAxisPaint = new Paint();
			m_MainAxisPaint.setColor(Color.RED);
			m_MainAxisPaint.setAntiAlias(true);
			m_MainAxisPaint.setStrokeWidth(5f);
			m_MainAxisPaint.setStyle(Paint.Style.STROKE);
			m_MainAxisPaint.setStrokeJoin(Paint.Join.ROUND);
			
			m_RotateCirclePaint = new Paint();
			m_RotateCirclePaint.setColor(Color.GREEN);
			m_RotateCirclePaint.setAntiAlias(true);
			m_RotateCirclePaint.setStrokeWidth(5f);
			m_RotateCirclePaint.setStyle(Paint.Style.STROKE);
			m_RotateCirclePaint.setStrokeJoin(Paint.Join.ROUND);
		}
		
		public void setSurfaceSize(int width, int height) {
			// synchronized so that canvas size does not get updated at the same time as a draw
			synchronized (m_SurfaceHolder) {
				m_SurfaceWidth = width;
				m_SurfaceHeight = height;
			}
		}
		
		@Override
		public void run() {
			while (m_IsRunning) {
				Canvas c = null;
				c = m_SurfaceHolder.lockCanvas();
				if (c != null) {
					synchronized (m_SurfaceHolder) {
						draw(c);
					}
					m_SurfaceHolder.unlockCanvasAndPost(c);
				}
			}
		}
		
		private void draw(Canvas c) {
			c.drawRect(0, 0, m_SurfaceWidth, m_SurfaceHeight, m_BackgroundPaint);
			
			drawPointerOverlay(c);
		}
		
		private void drawPointerOverlay(Canvas c) {
//TODO
			float ptr1X = View3D.this.m_GestureDetector.getPointer1X();
			float ptr1Y = View3D.this.m_GestureDetector.getPointer1Y();
			
			float ptr2X = View3D.this.m_GestureDetector.getPointer2X();
			float ptr2Y = View3D.this.m_GestureDetector.getPointer2Y();
			if (ptr1X != Float.NaN && ptr2X != Float.NaN) {
				c.drawLine(ptr1X, ptr1Y, ptr2X, ptr2Y, m_MainAxisPaint);
				
				float diffX = ptr1X - ptr2X;
				float diffY = ptr1Y - ptr2Y;
				float circleRadius = (float) Math.sqrt(diffX * diffX + diffY * diffY) / 2.0f;
				
				float midX = (ptr1X + ptr2X) / 2.0f;
				float midY = (ptr1Y + ptr2Y) / 2.0f;
				
				c.drawCircle(midX, midY, circleRadius, m_RotateCirclePaint);
				
				float ptr3X = View3D.this.m_GestureDetector.getPointer3X();
				float ptr3Y = View3D.this.m_GestureDetector.getPointer3Y();
				if (ptr3X != Float.NaN) {
					c.drawLine(midX, midY, ptr3X, ptr3Y, m_MainAxisPaint);
				}
			}
		}
	}

	@Override
	public boolean OnZoom(Navigation3DGestureDetector detector, float zoomFactor) {
//TODO
		return false;
	}

	@Override
	public boolean OnRotate(Navigation3DGestureDetector detector, float parallelAngle, float perpendicularRotate) {
//TODO
		return false;
	}

	@Override
	public boolean OnPan(Navigation3DGestureDetector detector, float xDistance, float yDistance) {
//TODO
		return false;
	}
}
